package com.imdroid.lite.activities;

import java.util.ArrayList;
import java.util.List;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.graphics.drawable.Drawable;
import android.location.Location;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.GestureDetector;
import android.view.GestureDetector.SimpleOnGestureListener;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import com.baidu.mapapi.BMapManager;
import com.baidu.mapapi.GeoPoint;
import com.baidu.mapapi.ItemizedOverlay;
import com.baidu.mapapi.LocationListener;
import com.baidu.mapapi.MKAddrInfo;
import com.baidu.mapapi.MKBusLineResult;
import com.baidu.mapapi.MKDrivingRouteResult;
import com.baidu.mapapi.MKLocationManager;
import com.baidu.mapapi.MKPoiResult;
import com.baidu.mapapi.MKSearch;
import com.baidu.mapapi.MKSearchListener;
import com.baidu.mapapi.MKSuggestionResult;
import com.baidu.mapapi.MKTransitRouteResult;
import com.baidu.mapapi.MKWalkingRouteResult;
import com.baidu.mapapi.MapActivity;
import com.baidu.mapapi.MapController;
import com.baidu.mapapi.MapView;
import com.baidu.mapapi.MyLocationOverlay;
import com.baidu.mapapi.OverlayItem;
import com.imdroid.lite.IMDroid;
import com.imdroid.lite.R;
import com.imdroid.lite.model.Destination;
import com.imdroid.lite.process.ProcessFactory;
import com.imdroid.lite.process.UserProcess;

public class NavigatorPointsPickup extends MapActivity implements
		LocationListener {
	/**
	 * The tag of the map activity
	 */
	private static final String TAG = "NavigatorPointsPickup";
	/**
	 * The map view;
	 */
	private MapView mapView;
	/**
	 * The map manager
	 */
	private BMapManager bMapManager;
	/**
	 * The controller of the map;
	 */
	private MapController mapController;
	/**
	 * The location manager
	 */
	private MKLocationManager locationManager;
	/**
	 * The MK Search
	 */
	private MKSearch mKSearch;
	/**
	 * The default zoon level
	 */
	private static final int defailtZoomLevel = 15;
	/**
	 * The overy lay of the my location
	 */
	private MyLocationOverlay myLocationOverlay;
	/**
	 * If keep the map in the center of my location
	 */
	private static boolean keepCenter = true;
	/**
	 * The address of this address name
	 */
	private static String addressName = null;
	/**
	 * The messages
	 */
	private static final int MESSAGE_SEND_DESTINATION = 0X101;
	private static final int MESSAGE_TEXT = 0X800;
	private static final int MESSAGE_SEND_OK = 0X102;
	private static final int MESSAGE_SEND_ERROR = 0X999;
	/**
	 * The handler of message.
	 */
	protected Handler messageHandler;
	/**
	 * The search full address
	 */
	private String searchFullAddress = null;
	/**
	 * 目的地层
	 */
	private DestinationOverlay destinationOverlay;
	/**
	 * The gesture detector
	 */
	private GestureDetector gestureDetector;

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.baidu.mapapi.MapActivity#onCreate(android.os.Bundle)
	 */
	public void onCreate(Bundle savedInstanceState) {
		// 初始化界面
		super.onCreate(savedInstanceState);
		setContentView(R.layout.loc_navigator_pick);
		initHandler();

		mapView = (MapView) this.findViewById(R.id.loc_mapview);
		// 初始化地图
		IMDroid app = (IMDroid) this.getApplication();
		bMapManager = app.mBMapMan;
		super.initMapActivity(app.mBMapMan);
		// 初始化MKSearch类:
		mKSearch = new MKSearch();
		mKSearch.init(bMapManager, mapSearchListener);
		// 设置手势的处理
		gestureDetector = new GestureDetector(this, new MapGestureListener());

		mapView.setOnTouchListener(new OnTouchListener() {
			@Override
			public boolean onTouch(View v, MotionEvent event) {
				gestureDetector.onTouchEvent(event);
				return false;
			}
		});
		// 设置地图中心
		mapController = mapView.getController();
		mapController.setZoom(defailtZoomLevel);
		mapView.setDoubleClickZooming(true);
		mapView.setDrawOverlayWhenZooming(true);
		mapView.setBuiltInZoomControls(false);
		mapView.setLongClickable(true);
		// 添加图层
		myLocationOverlay = new MyLocationOverlay(this, mapView);
		myLocationOverlay.enableMyLocation();
		myLocationOverlay.enableCompass();
		mapView.getOverlays().add(myLocationOverlay);

		// 定义软键盘的“搜查”按钮的定义
		EditText editText = (EditText) this
				.findViewById(R.id.loc_address_keyword);
		editText.setOnEditorActionListener(new EditText.OnEditorActionListener() {
			public boolean onEditorAction(TextView v, int actionId,
					KeyEvent event) {
				if (actionId == EditorInfo.IME_ACTION_SEARCH) {
					InputMethodManager imm = (InputMethodManager) v
							.getContext().getSystemService(
									Context.INPUT_METHOD_SERVICE);
					imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
					NavigatorPointsPickup.this
							.search(NavigatorPointsPickup.this
									.findViewById(R.id.loc_btn_search));
					return true;
				}
				return false;
			}

		});

	}

	@SuppressLint("HandlerLeak")
	private void initHandler() {
		messageHandler = new Handler() {
			public void handleMessage(Message msg) {
				try {
					processedMessage(msg);
				} catch (Exception e) {
					e.printStackTrace();
					Toast.makeText(IMDroid.getAppContext(), e.getMessage(),
							Toast.LENGTH_SHORT).show();
				}
			}
		};
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.baidu.mapapi.MapActivity#onResume()
	 */
	protected void onResume() {
		super.onResume();
		if (bMapManager != null) {
			bMapManager.start();
		}
		// 设置location manager
		locationManager = bMapManager.getLocationManager();
		locationManager.requestLocationUpdates(this);

		Log.d(TAG, "AddressName: " + addressName);
		if (this.getIntent().getExtras() != null) {
			addressName = this.getIntent().getExtras().getString("addressName");
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.baidu.mapapi.MapActivity#onPause()
	 */
	protected void onPause() {
		if (locationManager != null)
			locationManager.removeUpdates(this);

		if (bMapManager != null) {
			bMapManager.stop();
		}

		super.onPause();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.baidu.mapapi.MapActivity#onDestroy()
	 */
	protected void onDestroy() {
		super.onPause();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.baidu.mapapi.MapActivity#isRouteDisplayed()
	 */
	protected boolean isRouteDisplayed() {
		return false;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.baidu.mapapi.LocationListener#onLocationChanged(android.location.
	 * Location)
	 */
	public void onLocationChanged(Location location) {
		if (location != null && keepCenter) {
			final GeoPoint pt = new GeoPoint(
					(int) (location.getLatitude() * 1000000),
					(int) (location.getLongitude() * 1000000));
			mapController.setCenter(pt);
			keepCenter = false;
		}
	}

	/**
	 * The action when clicking the back button
	 * 
	 * @param view
	 *            the button of back
	 */
	public void back(View view) {
		finish();
	}

	/**
	 * Search address
	 * 
	 * @param view
	 *            the button of view
	 */
	public void search(View view) {
		EditText keyWord = (EditText) this
				.findViewById(R.id.loc_address_keyword);
		if (keyWord.getText() == null || keyWord.getText().length() <= 0) {
			Toast.makeText(this, this.getString(R.string.loc_no_address),
					Toast.LENGTH_LONG).show();
			return;
		}
		searchFullAddress = keyWord.getText() + "";
		// 查询地址
		mKSearch.suggestionSearch(searchFullAddress);
		// 打开提示框
		ProgressDialogHelper.showProgress(this, R.string.loc_address_title,
				R.string.loc_address_wait);
		// 收起软键盘
		InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
		imm.hideSoftInputFromWindow(this.getCurrentFocus().getWindowToken(), 0);
	}

	/**
	 * process the message
	 * 
	 * @param msg
	 *            the message the message
	 * 
	 * @throws Exception
	 */
	private void processedMessage(Message msg) throws Exception {
		switch (msg.what) {
		case MESSAGE_SEND_DESTINATION:
			// 退出队伍
			sendDestination((Destination) msg.obj);
			break;
		case MESSAGE_SEND_OK:

		case MESSAGE_TEXT:
			Toast.makeText(IMDroid.getAppContext(), ((String) msg.obj),
					Toast.LENGTH_LONG).show();
			break;
		case MESSAGE_SEND_ERROR:
			Toast.makeText(IMDroid.getAppContext(),
					((Exception) msg.obj).getMessage(), Toast.LENGTH_LONG)
					.show();
			break;
		}
	}

	/**
	 * Send the destination
	 * 
	 * @param destination
	 *            the destination to be send
	 * @throws Exception
	 */
	private void sendDestination(final Destination destination)
			throws Exception {
		// 设置屏幕中心
		if (destination != null) {
			final GeoPoint pt = new GeoPoint(
					(int) (destination.getLatitude() * 1000000),
					(int) (destination.getLongitude() * 1000000));
			mapController.setCenter(pt);
		}
		// 设置常用地址
		if (addressName != null && addressName.length() > 0) {
			destination.setName(addressName);
			Destination.saveDestination(destination);
		} else {// 如果想跳过，就开始一个一个往下排历史记录
			destination.setName("History");

			Destination.saveDestinationAsHistory(destination);
		}

		ProgressDialogHelper.showProgress(this, R.string.loc_wait_title,
				R.string.loc_wait_text);
		new Thread() {
			public void run() {
				try {
					// 通过服务器发送地址
					UserProcess process = (UserProcess) ProcessFactory
							.getProcess(UserProcess.class);
					process.sendDestination(destination,
							NavigatorPointsPickup.this);

					messageHandler.post(new Runnable() {
						/*
						 * (non-Javadoc)
						 * 
						 * @see java.lang.Runnable#run()
						 */
						public void run() {
							// 提示成功
							final Activity activity = NavigatorPointsPickup.this;
							AlertDialog.Builder buidler = new AlertDialog.Builder(
									activity);
							buidler.setMessage(activity
									.getString(R.string.loc_send_success));
							buidler.setPositiveButton("Ok",
									new OnClickListener() {
										public void onClick(
												DialogInterface arg0, int arg1) {
											// 返回主界面
											// activity.startActivity(new
											// Intent(
											// activity,
											// MainActivity.class));
											activity.finish();
										}
									});
							buidler.show();

						}
					});
					// 提示成功
					// messageHandler.obtainMessage(
					// MESSAGE_TEXT,
					// NavigatorPointsPickup.this
					// .getString(R.string.loc_send_success))
					// .sendToTarget();

				} catch (Exception ex) {
					ex.printStackTrace();
					messageHandler.obtainMessage(MESSAGE_SEND_ERROR, ex)
							.sendToTarget();
				} finally {
					ProgressDialogHelper.dismissProgress();
				}
			}
		}.start();

	}

	/**
	 * The seach listener of the map
	 */
	private MKSearchListener mapSearchListener = new MKSearchListener() {
		/**
		 * The name of the destination;
		 */
		public String destinationAddress;

		/*
		 * (non-Javadoc)
		 * 
		 * @see
		 * com.baidu.mapapi.MKSearchListener#onGetAddrResult(com.baidu.mapapi
		 * .MKAddrInfo, int)
		 */
		public void onGetAddrResult(final MKAddrInfo result, int error) {
			// 解除对话框
			ProgressDialogHelper.dismissProgress();
			Context context = NavigatorPointsPickup.this;

			// 如果百度查找有错
			if (error != 0) {
				Toast.makeText(
						NavigatorPointsPickup.this,
						context.getString(R.string.loc_map_destination_error)
								+ "(Error Code:" + error + ")",
						Toast.LENGTH_LONG).show();
				return;
			}

			// 设置地图中心
			if (result.geoPt != null)
				mapController.setCenter(result.geoPt);
			// 如果搜索地址为空（即从长按中进入）
			if (searchFullAddress == null) {
				// 弹出对话框
				AlertDialog.Builder buidler = new AlertDialog.Builder(
						NavigatorPointsPickup.this);
				buidler.setTitle(R.string.loc_address_title);
				// 确认文字
				String text = NavigatorPointsPickup.this
						.getString(R.string.loc_address_confirm);
				text = text.replace("%1%", result.strAddr);
				buidler.setMessage(text);
				buidler.setIcon(android.R.drawable.ic_dialog_info);

				// 按钮 - 发送
				buidler.setPositiveButton(NavigatorPointsPickup.this
						.getString(R.string.loc_dia_sy), new OnClickListener() {
					public void onClick(DialogInterface arg0, int arg1) {
						Message msg = new Message();
						destinationAddress = result.strAddr;
						Destination d = new Destination();
						d.setAddress(destinationAddress);
						d.setLatitude((float) (result.geoPt.getLatitudeE6() / 1e6));
						d.setLongitude((float) (result.geoPt.getLongitudeE6() / 1e6));

						msg.what = MESSAGE_SEND_DESTINATION;
						msg.obj = d;
						// 发送目的地给车机
						messageHandler.sendMessage(msg);
					}
				});
				// 按钮 - 取消
				buidler.setNegativeButton(NavigatorPointsPickup.this
						.getString(R.string.loc_dia_sn), new OnClickListener() {
					public void onClick(DialogInterface arg0, int arg1) {
						return;
					}
				});
				buidler.show();
			} else {

				// 发送目的地
				Destination d = new Destination();
				d.setAddress(destinationAddress);
				d.setLatitude((float) (result.geoPt.getLatitudeE6() / 1e6));
				d.setLongitude((float) (result.geoPt.getLongitudeE6() / 1e6));
				// 添加目的地图层
				if (destinationOverlay != null)
					mapView.getOverlays().remove(destinationOverlay);

				destinationOverlay = new DestinationOverlay(d, context
						.getResources().getDrawable(R.drawable.icon_marka));

				mapView.getOverlays().add(destinationOverlay);
				mapView.invalidate();
				mapView.getController().animateTo(result.geoPt);
			}
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see
		 * com.baidu.mapapi.MKSearchListener#onGetBusDetailResult(com.baidu.
		 * mapapi.MKBusLineResult, int)
		 */
		public void onGetBusDetailResult(MKBusLineResult result, int error) {

		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see
		 * com.baidu.mapapi.MKSearchListener#onGetDrivingRouteResult(com.baidu
		 * .mapapi.MKDrivingRouteResult, int)
		 */
		@Override
		public void onGetDrivingRouteResult(MKDrivingRouteResult arg0, int arg1) {

		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see
		 * com.baidu.mapapi.MKSearchListener#onGetPoiDetailSearchResult(int,
		 * int)
		 */
		@Override
		public void onGetPoiDetailSearchResult(int arg0, int arg1) {

		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see
		 * com.baidu.mapapi.MKSearchListener#onGetPoiResult(com.baidu.mapapi
		 * .MKPoiResult, int, int)
		 */
		public void onGetPoiResult(final MKPoiResult res, int type, int error) {
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see
		 * com.baidu.mapapi.MKSearchListener#onGetRGCShareUrlResult(java.lang
		 * .String, int)
		 */
		@Override
		public void onGetRGCShareUrlResult(String arg0, int arg1) {

		}

		@Override
		public void onGetSuggestionResult(MKSuggestionResult result, int iError) {
			// 如果没有找到目的地
			if (iError != 0 || result == null || result.getSuggestionNum() <= 0) {
				Log.d(TAG, "Search by full address....");
				ProgressDialogHelper.dismissProgress();

				// 如果找不到建议，则通过地址解释查找
				destinationAddress = searchFullAddress;
				mKSearch.geocode(searchFullAddress, null);

				return;
			}

			// 把目的地组成数组，准备显示选择
			int nSize = result.getSuggestionNum();
			final String[] mStrSuggestions = new String[nSize];
			for (int i = 0; i < nSize; i++)
				mStrSuggestions[i] = result.getSuggestion(i).city + "-"
						+ result.getSuggestion(i).key;
			destinationAddress = null;
			// 弹出对话框
			AlertDialog.Builder buidler = new AlertDialog.Builder(
					NavigatorPointsPickup.this);
			buidler.setTitle(R.string.loc_map_destination_name);
			buidler.setIcon(android.R.drawable.ic_dialog_info);
			buidler.setSingleChoiceItems(mStrSuggestions, 0,
					new DialogInterface.OnClickListener() {
						public void onClick(DialogInterface dialog, int which) {
							// 记下选择的地址
							destinationAddress = mStrSuggestions[which];
						}
					});
			// 按钮 - 发送
			buidler.setPositiveButton(
					NavigatorPointsPickup.this.getString(R.string.loc_dia_sy),
					new OnClickListener() {
						public void onClick(DialogInterface arg0, int arg1) {
							destinationAddress = (destinationAddress != null) ? destinationAddress
									: mStrSuggestions[0];
							// 将地址再转为坐标
							String city = destinationAddress.substring(0,
									destinationAddress.indexOf("-"));
							String key = destinationAddress.substring(
									destinationAddress.indexOf("-"),
									destinationAddress.length());
							Log.d(TAG, "select key:" + key + "city:" + city);
							mKSearch.geocode(key, city);
						}
					});
			// 按钮 - 取消
			buidler.setNegativeButton(
					NavigatorPointsPickup.this.getString(R.string.loc_dia_sn),
					new OnClickListener() {
						public void onClick(DialogInterface arg0, int arg1) {
							// 解除对话框
							ProgressDialogHelper.dismissProgress();
						}
					});
			buidler.show();
		}

		@Override
		public void onGetTransitRouteResult(MKTransitRouteResult arg0, int arg1) {

		}

		@Override
		public void onGetWalkingRouteResult(MKWalkingRouteResult arg0, int arg1) {

		}

	};

	/**
	 * The gesture detctor
	 */
	/**
	 * The map gesture linstener
	 * 
	 */
	private class MapGestureListener extends SimpleOnGestureListener {
		/*
		 * (non-Javadoc)
		 * 
		 * @see android.view.GestureDetector.OnGestureListener#onLongPress
		 * (android.view.MotionEvent)
		 */
		public void onLongPress(MotionEvent e) {
			final GeoPoint myGeoPoint = mapView.getProjection().fromPixels(
					(int) e.getX(), (int) e.getY());
			if (myGeoPoint == null)
				return;
			searchFullAddress = null;

			ProgressDialogHelper.showProgress(NavigatorPointsPickup.this,
					R.string.loc_address_title, R.string.loc_address_wait);

			mKSearch.reverseGeocode(new GeoPoint(myGeoPoint.getLatitudeE6(),
					myGeoPoint.getLongitudeE6()));

		}
	}

	/**
	 * Show the alert dialog
	 * 
	 * @param message
	 *            The message
	 * @param ctx
	 *            The context
	 */
	protected void showAlert(String message) {
		AlertDialog.Builder buidler = new AlertDialog.Builder(this);
		buidler.setMessage(message);

		buidler.setPositiveButton("Ok", new OnClickListener() {
			public void onClick(DialogInterface arg0, int arg1) {
			}
		});
		buidler.show();
	}

	/**
	 * The overlay of the destination
	 * 
	 */
	private class DestinationOverlay extends ItemizedOverlay<OverlayItem> {
		public List<OverlayItem> mGeoList = new ArrayList<OverlayItem>();
		/**
		 * 目的地
		 */
		Destination destination;

		/**
		 * The default cosntructor
		 */
		public DestinationOverlay(Destination destination, Drawable arg0) {
			super(arg0);
			this.destination = destination;
			GeoPoint p1 = new GeoPoint((int) (destination.getLatitude() * 1E6),
					(int) (destination.getLongitude() * 1E6));
			mGeoList.add(new OverlayItem(p1, "P1", "point1"));
			populate();
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see com.baidu.mapapi.ItemizedOverlay#onTap(int)
		 */
		protected boolean onTap(int index) {
			final Activity actvity = NavigatorPointsPickup.this;
			String text = actvity.getString(R.string.loc_address_confirm);
			text = text.replace("%1%", destination.getAddress());
			// 弹出对话框
			AlertDialog.Builder buidler = new AlertDialog.Builder(actvity);
			buidler.setMessage(text);
			// 按钮 - 发送
			buidler.setPositiveButton(
					NavigatorPointsPickup.this.getString(R.string.loc_dia_okay),
					new OnClickListener() {
						public void onClick(DialogInterface arg0, int arg1) {
							Message msg = new Message();
							msg.what = MESSAGE_SEND_DESTINATION;
							msg.obj = destination;
							// 发送目的地给车机
							messageHandler.sendMessage(msg);
						}
					});
			// 按钮 - 取消
			buidler.setNegativeButton(
					NavigatorPointsPickup.this.getString(R.string.loc_dia_sn),
					new OnClickListener() {
						public void onClick(DialogInterface arg0, int arg1) {
							return;
						}
					});
			buidler.show();

			return true;
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see com.baidu.mapapi.ItemizedOverlay#createItem(int)
		 */
		protected OverlayItem createItem(int arg0) {
			return mGeoList.get(arg0);
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see com.baidu.mapapi.ItemizedOverlay#size()
		 */
		public int size() {
			return mGeoList.size();
		}
	}
}
